#!/usr/bin/env python3
"""
字体解码器基础测试模块

验证核心功能，不依赖外部库如selenium等。
符合openUBMC社区开发标准。
"""

import unittest
import tempfile
import shutil
from pathlib import Path
from unittest.mock import Mock, patch

import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src'))

# 尝试导入，如果失败则跳过相关测试
try:
    from utils.font_decoder import FontDecoder, AdvancedFontDecoder, FontReplacer
    from utils.font_constants import (
        UnicodeRanges, FontConstants, TextAnalysisConstants, ErrorCodes
    )
    IMPORTS_AVAILABLE = True
except ImportError as e:
    IMPORTS_AVAILABLE = False
    IMPORT_ERROR = str(e)


class TestFontConstants(unittest.TestCase):
    """测试字体常量定义"""

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_unicode_ranges(self):
        """测试Unicode范围常量"""
        self.assertEqual(UnicodeRanges.CJK_UNIFIED_IDEOGRAPHS_START, 0x4E00)
        self.assertEqual(UnicodeRanges.CJK_UNIFIED_IDEOGRAPHS_END, 0x9FFF)
        self.assertEqual(UnicodeRanges.DIGITS_START, 0x0030)
        self.assertEqual(UnicodeRanges.DIGITS_END, 0x0039)

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_font_constants(self):
        """测试字体常量"""
        self.assertEqual(FontConstants.DEFAULT_CACHE_DIR, "font_cache")
        self.assertEqual(FontConstants.MAX_FONT_FILE_SIZE, 10 * 1024 * 1024)
        self.assertIn('.woff', FontConstants.FONT_EXTENSIONS)
        self.assertIn('.woff2', FontConstants.FONT_EXTENSIONS)

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_text_analysis_constants(self):
        """测试文本分析常量"""
        self.assertEqual(TextAnalysisConstants.UNKNOWN_CHAR_THRESHOLD, 0.3)
        self.assertGreater(TextAnalysisConstants.MAX_TEXT_LENGTH,
                          TextAnalysisConstants.MIN_TEXT_LENGTH)


class TestFontDecoder(unittest.TestCase):
    """测试字体解码器基础功能"""

    def setUp(self):
        """设置测试环境"""
        if IMPORTS_AVAILABLE:
            self.temp_dir = tempfile.mkdtemp()
            self.decoder = FontDecoder(self.temp_dir)

    def tearDown(self):
        """清理测试环境"""
        if hasattr(self, 'temp_dir'):
            shutil.rmtree(self.temp_dir, ignore_errors=True)

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_extract_font_urls_font_face(self):
        """测试从@font-face规则提取字体URL"""
        html_content = """
        <style>
        @font-face {
            font-family: 'CustomFont';
            src: url('/assets/font/custom.woff2') format('woff2');
        }
        </style>
        """
        base_url = "https://example.com"
        font_urls = self.decoder.extract_font_urls(html_content, base_url)

        self.assertEqual(len(font_urls), 1)
        self.assertEqual(font_urls[0], "https://example.com/assets/font/custom.woff2")

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_extract_font_urls_link_tag(self):
        """测试从link标签提取字体URL"""
        html_content = '<link href="/fonts/custom.woff" rel="stylesheet">'
        base_url = "https://example.com"
        font_urls = self.decoder.extract_font_urls(html_content, base_url)

        self.assertEqual(len(font_urls), 1)
        self.assertEqual(font_urls[0], "https://example.com/fonts/custom.woff")

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_decode_text(self):
        """测试文字解码功能"""
        mapping_table = {
            'A': '杭',
            'B': '州',
            'C': '市'
        }
        garbled_text = "ABC"
        decoded_text = self.decoder.decode_text(garbled_text, mapping_table)

        self.assertEqual(decoded_text, "杭州市")

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_decode_text_empty_mapping(self):
        """测试空映射表的解码"""
        garbled_text = "ABC"
        decoded_text = self.decoder.decode_text(garbled_text, {})

        self.assertEqual(decoded_text, "ABC")


class TestAdvancedFontDecoder(unittest.TestCase):
    """测试高级字体解码器"""

    def setUp(self):
        """设置测试环境"""
        if IMPORTS_AVAILABLE:
            self.decoder = AdvancedFontDecoder()

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_analyze_text_patterns_chinese(self):
        """测试中文文本模式分析"""
        text = "杭州市政府"
        patterns = self.decoder.analyze_text_patterns(text)

        self.assertEqual(patterns['chinese_chars'], 5)
        self.assertEqual(patterns['numbers'], 0)
        self.assertEqual(patterns['punctuation'], 0)
        self.assertEqual(patterns['unknown_chars'], 0)

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_analyze_text_patterns_mixed(self):
        """测试混合文本模式分析"""
        text = "杭州市2023年"
        patterns = self.decoder.analyze_text_patterns(text)

        self.assertEqual(patterns['chinese_chars'], 4)
        self.assertEqual(patterns['numbers'], 4)
        self.assertEqual(patterns['punctuation'], 0)
        self.assertEqual(patterns['unknown_chars'], 0)

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_analyze_text_patterns_with_punctuation(self):
        """测试带标点的文本模式分析"""
        text = "你好，世界！"
        patterns = self.decoder.analyze_text_patterns(text)

        self.assertEqual(patterns['chinese_chars'], 4)
        self.assertEqual(patterns['numbers'], 0)
        self.assertEqual(patterns['punctuation'], 2)
        self.assertEqual(patterns['unknown_chars'], 0)


class TestFontReplacer(unittest.TestCase):
    """测试字体替换器"""

    def setUp(self):
        """设置测试环境"""
        if IMPORTS_AVAILABLE:
            self.replacer = FontReplacer()

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_system_fonts_list(self):
        """测试系统字体列表"""
        self.assertIsInstance(self.replacer.system_fonts, list)
        self.assertIn('Arial', self.replacer.system_fonts)
        self.assertIn('Microsoft YaHei', self.replacer.system_fonts)


class TestErrorCodes(unittest.TestCase):
    """测试错误代码"""

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_error_codes_defined(self):
        """测试错误代码定义"""
        self.assertEqual(ErrorCodes.SUCCESS, 0)
        self.assertGreater(ErrorCodes.FONT_DOWNLOAD_FAILED, 1000)
        self.assertGreater(ErrorCodes.FONT_PARSE_FAILED, 1000)
        self.assertGreater(ErrorCodes.OCR_INIT_FAILED, 1000)


class TestConstantsIntegrity(unittest.TestCase):
    """测试常量完整性"""

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_no_magic_numbers_in_ranges(self):
        """测试Unicode范围没有魔鬼数字"""
        # 验证中文字符范围是合理的
        self.assertLess(UnicodeRanges.CJK_UNIFIED_IDEOGRAPHS_START,
                       UnicodeRanges.CJK_UNIFIED_IDEOGRAPHS_END)

        # 验证数字字符范围是合理的
        self.assertLess(UnicodeRanges.DIGITS_START, UnicodeRanges.DIGITS_END)
        self.assertEqual(UnicodeRanges.DIGITS_END - UnicodeRanges.DIGITS_START, 9)  # 0-9共10个数字

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_font_extensions_completeness(self):
        """测试字体扩展名列表的完整性"""
        required_extensions = ['.woff', '.woff2', '.ttf', '.otf', '.eot']
        for ext in required_extensions:
            self.assertIn(ext, FontConstants.FONT_EXTENSIONS)

    @unittest.skipUnless(IMPORTS_AVAILABLE, f"Import failed: {IMPORT_ERROR if not IMPORTS_AVAILABLE else ''}")
    def test_threshold_values_reasonable(self):
        """测试阈值设置的合理性"""
        # 未知字符阈值应该在0-1之间
        self.assertGreater(TextAnalysisConstants.UNKNOWN_CHAR_THRESHOLD, 0)
        self.assertLess(TextAnalysisConstants.UNKNOWN_CHAR_THRESHOLD, 1)

        # 文本长度限制应该合理
        self.assertGreater(TextAnalysisConstants.MIN_TEXT_LENGTH, 0)
        self.assertLess(TextAnalysisConstants.MAX_TEXT_LENGTH, 1000000)  # 不超过1M字符


if __name__ == '__main__':
    # 检查导入状态
    if not IMPORTS_AVAILABLE:
        print(f"⚠️  警告: 无法导入字体解码器模块: {IMPORT_ERROR}")
        print("请确保依赖已正确安装: pip install -r requirements.txt")

    # 设置测试套件
    test_suite = unittest.TestSuite()

    # 添加测试用例
    test_classes = [
        TestFontConstants,
        TestFontDecoder,
        TestAdvancedFontDecoder,
        TestFontReplacer,
        TestErrorCodes,
        TestConstantsIntegrity
    ]

    for test_class in test_classes:
        tests = unittest.TestLoader().loadTestsFromTestCase(test_class)
        test_suite.addTests(tests)

    # 运行测试
    runner = unittest.TextTestRunner(verbosity=2)
    result = runner.run(test_suite)

    # 输出测试结果
    if result.wasSuccessful():
        print("\n✅ 所有测试通过！字体解码器基础功能正常。")
        if IMPORTS_AVAILABLE:
            print("📝 常量定义符合openUBMC开发规范，无魔鬼数字。")
        exit(0)
    else:
        print(f"\n❌ 测试失败: {len(result.failures)} 个失败, {len(result.errors)} 个错误")
        for test, traceback in result.failures + result.errors:
            print(f"失败的测试: {test}")
            print(f"错误信息: {traceback}")
        exit(1)
